package org.tinygroup.earthworm3;

import java.util.Queue;
import java.util.concurrent.atomic.AtomicInteger;

public class RpcContext3 extends WormBaseContext3 {
	
	private static final ThreadLocal<RpcContext3> threadLocal = new ThreadLocal<RpcContext3>();
	RpcContext3 parent;
	RpcContext3 local;
	private long startTime;
	private int span0;
	private int span1;
	
	RpcContext3(String _traceId, String _spanId) {
		this(_traceId, _spanId,null);
	}
	RpcContext3(String _traceId, String _rpcId, RpcContext3 _parentRpc) {
        this(_traceId, _rpcId, _parentRpc, new AtomicInteger(1));
    }

	RpcContext3(String _traceId, String _rpcId, RpcContext3 _parentRpc, AtomicInteger _childRpcIdx
			) {
		super(_traceId, _rpcId);
		this.parent = _parentRpc;
		this.childIdx = _childRpcIdx;
	}

	public static RpcContext3 get() {
		return (RpcContext3) threadLocal.get();
	}
	public static void set(RpcContext3 rpc){
		threadLocal.set(rpc);
	}
	
	
	public void startLocal(String traceName){
		startLocal("","",traceName);
	}
	public void startLocal(String serviceId,String method){
		startLocal(serviceId, method, "");
	}
	public void startLocal(String serviceId,String method,String traceName){
		RpcContext3 localContext = null;
		if(local==null){
			localContext = new RpcContext3(this.traceId, getNextChild());
			local = localContext;
			
		}else{
			localContext = new RpcContext3(this.traceId, local.getNextChild());
			localContext.parent = local;
			local = localContext;
		}
		
		localContext.serviceId = serviceId;
		localContext.methodName = method;
		localContext.traceName = traceName;
		
		localContext.startTime = System.currentTimeMillis();
		localContext.span0 = 0;
		
	}
	public void endLocal(){
		if(local==null){
			return;
		}
		local = local.parent;
	}

	public void startRpc(String serviceId, String methodName) {
		RpcContext3 localContext = new RpcContext3(this.traceId, getNextChild());
		localContext.serviceId = serviceId;
		localContext.methodName = methodName;
		localContext.traceName = traceName;
		localContext.parent = this;
		localContext.startTime = System.currentTimeMillis();
		localContext.span0=0;
		threadLocal.set(localContext);

	
	}

	public void rpcClientSend() {
		this.span0 = (int) (System.currentTimeMillis() - this.startTime);
	}
	
	public void endRpc() {
		threadLocal.set(this.parent);
		this.span1 = (int) (System.currentTimeMillis() - this.startTime);
	}
	public void rpcServerRecv(String serviceId, String methodName) {
		this.startTime = System.currentTimeMillis();
		this.serviceId = serviceId;
		this.methodName = methodName;
	}

	public void rpcServerSend() {
		this.span1 = (int) (System.currentTimeMillis() - this.startTime);
	}
	public void startTrace(String name) {
		this.startTime = System.currentTimeMillis();
		this.traceName = name;
	}

	public void endTrace() {
		this.span1 = (int) (System.currentTimeMillis() - this.startTime);
	}
	
	public RpcContext3 createChildRpc() {
		RpcContext3 localContext = new RpcContext3(this.traceId, getNextChild());
		localContext.serviceId = serviceId;
		localContext.methodName = methodName;
		localContext.traceName = traceName;
		localContext.parent = this;
		localContext.startTime = System.currentTimeMillis();
		return localContext;
	}
}
